﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace Spk.Controls.Common
{
    public static class Drawing
    {
        public static Color Brighten(Color color, byte percent)
        {
            if (percent > 100)
                throw new ArgumentException("Invalid percent value!");

            return Color.FromArgb(
                color.A,
                (int)(color.R + (255 - color.R) * (percent / 100.0f)),
                (int)(color.G + (255 - color.G) * (percent / 100.0f)),
                (int)(color.B + (255 - color.B) * (percent / 100.0f)));
        }

        public static Color Darken(Color color, byte percent)
        {
            if (percent > 100)
                throw new ArgumentException("Invalid percent value!");

            return Color.FromArgb(
                color.A,
                (int)(color.R * (1.0f - percent / 100.0f)),
                (int)(color.G * (1.0f - percent / 100.0f)),
                (int)(color.B * (1.0f - percent / 100.0f)));
        }

        public static Color SetOpacity(Color color, byte opacity)
        {
            return Color.FromArgb(opacity, color.R, color.G, color.B);
        }

        // Rounded rectangle utils

        public static GraphicsPath CreateRoundRectPath(RectangleF rect, float radius)
        {
            float diameter = radius * 2;

            GraphicsPath path = new GraphicsPath();
            path.AddArc(new RectangleF(rect.Left, rect.Top, diameter, diameter), 180, 90);
            path.AddArc(new RectangleF(rect.Right - 1 - diameter, rect.Top, diameter, diameter), 270, 90);
            path.AddArc(new RectangleF(rect.Right - 1 - diameter, rect.Bottom - 1 - diameter, diameter, diameter), 0, 90);
            path.AddArc(new RectangleF(rect.Left, rect.Bottom - 1 - diameter, diameter, diameter), 90, 90);
            path.AddLine(new PointF(rect.Left, rect.Bottom - radius), new PointF(rect.Left, rect.Top + radius));
            return path;
        }

        public static GraphicsPath CreateRoundRectPath(RectangleF rect, float ltRadius, float rtRadius, float rbRadius, float lbRadius)
        {
            GraphicsPath path = new GraphicsPath();

            path.AddArc(new RectangleF(rect.Left, rect.Top, 2 * ltRadius, 2 * ltRadius), 180, 90);
            path.AddArc(new RectangleF(rect.Right - 2 * rtRadius, rect.Top, 2 * rtRadius, 2 * rtRadius), 270, 90);
            path.AddArc(new RectangleF(rect.Right - 2 * rbRadius, rect.Bottom - 2 * rbRadius, 2 * rbRadius, 2 * rbRadius), 0, 90);
            path.AddArc(new RectangleF(rect.Left, rect.Bottom - 2 * lbRadius, 2 * lbRadius, 2 * lbRadius), 90, 90);
            path.AddLine(new PointF(rect.Left, rect.Bottom - lbRadius), new PointF(rect.Left, rect.Top + ltRadius));
            return path;
        }

        public static void DrawRoundRect(System.Drawing.Graphics g, Pen pen, RectangleF rect, float radius, bool antiAlias = true)
        {
            SmoothingMode originalSmoothingMode = g.SmoothingMode;
            if (antiAlias)
                g.SmoothingMode = SmoothingMode.AntiAlias;

            using (GraphicsPath path = CreateRoundRectPath(rect, radius))
                g.DrawPath(pen, path);

            if (antiAlias)
                g.SmoothingMode = originalSmoothingMode;
        }

        public static void DrawRoundRect(System.Drawing.Graphics g, Pen pen, RectangleF rect, float ltRadius, float rtRadius, float rbRadius, float lbRadius, bool antiAlias = true)
        {
            SmoothingMode originalSmoothingMode = g.SmoothingMode;
            if (antiAlias)
                g.SmoothingMode = SmoothingMode.AntiAlias;

            using (GraphicsPath path = CreateRoundRectPath(rect, ltRadius, rtRadius, rbRadius, lbRadius))
                g.DrawPath(pen, path);

            if (antiAlias)
                g.SmoothingMode = originalSmoothingMode;
        }

        public static void FillRoundRect(System.Drawing.Graphics g, Brush brush, RectangleF rect, float radius, bool antiAlias = true)
        {
            SmoothingMode originalSmoothingMode = g.SmoothingMode;
            if (antiAlias)
                g.SmoothingMode = SmoothingMode.AntiAlias;

            using (GraphicsPath path = CreateRoundRectPath(rect, radius))
                g.FillPath(brush, path);

            if (antiAlias)
                g.SmoothingMode = originalSmoothingMode;
        }

        public static Rectangle CreateGradientRect(Rectangle rect)
        {
            Rectangle result = rect;
            if (result.Width % 2 == 1)
                result.Width++;
            if (result.Height % 2 == 1)
                result.Height++;

            return result;
        }

        public static Rectangle ConvertToApiRect(Rectangle rect)
        {
            return new Rectangle(rect.Location, new Size(rect.Width - 1, rect.Height - 1));
        }
    }
}
